package com.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.constant.MqttMessageType;
import com.dao.AdvertisementMapper;
import com.dao.PlacedHospitalMapper;
import com.dao.VenderDeviceMapper;
import com.emqx.MqttMessageDTO;
import com.emqx.MqttMessageSender;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.model.AdvertSmarPart;
import com.model.Advertisement;
import com.model.PlacedHospital;
import com.model.VenderDevice;
import com.page.GenericPage;
import com.po.*;
import com.result.Result;
import com.service.AdvertiesementService;
import com.utils.CurrentLoginUserAgent;
import com.utils.SessionUtil;
import com.vo.AdvertisementVO;
import com.vo.CustomerVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
public class AdvertiesementServiceImpl implements AdvertiesementService {

    @Autowired
    private AdvertisementMapper advertisementMapper;


    @Autowired
    private PlacedHospitalMapper placedHospitalMapper;

    @Autowired
    private VenderDeviceMapper venderDeviceMapper;


    @Autowired
    private MqttMessageSender mqttMessageSender;

    @Override
    public Result<AdvertisementVO> save(AdvertisementPO advertisementPO) {

        if (SessionUtil.getCurrentUserType() == 1) {
            return new Result<>().error("超级管理员不能创建广告");
        }
        Long businessId = CurrentLoginUserAgent.getBusinessId();
        //执行广告的保存操作
        Advertisement advertisement = new Advertisement();
        BeanUtils.copyProperties(advertisementPO, advertisement);
        Date time = new Date();
        advertisement.setCreateTime(time);
        advertisement.setAgent(businessId);
        advertisement.setUpdateTime(time);
        advertisement.setCreated(CurrentLoginUserAgent.getUser().getUserName());
        advertisement.setUpdated(CurrentLoginUserAgent.getUser().getUserName());
        advertisement.setStatus(1); //未发布
        advertisement.setBody(JSON.toJSONString(advertisementPO.getList()));
        long count = advertisementMapper.insertSelective(advertisement);
        AdvertisementVO advertisementVO = new AdvertisementVO();
        advertisementVO.setUpdateTime(time);
        advertisement.setCreateTime(time);
        BeanUtils.copyProperties(advertisement, advertisementVO);
        advertisementVO.setList(advertisementPO.getList());
        return new Result<AdvertisementVO>().ok(advertisementVO);
    }

    @Override
    public Result<Boolean> removeById(Long id) {
        int count = advertisementMapper.deleteByPrimaryKey(id);
        return new Result<>().ok();
    }

    @Override
    public Result<Boolean> removeAllByIds(List<Long> list) {
        Long[] ids = (Long[]) list.toArray(new Long[list.size()]);
        advertisementMapper.deleteByPrimaryKeys(ids);
        return new Result<>().ok();
    }

    @Override
    public Result<Boolean> modify(AdvertisementUpdatePo advertisementUpdatePo) {

        Advertisement preAdv = advertisementMapper.selectByPrimaryKey(advertisementUpdatePo.getId());
        Advertisement advertisement = new Advertisement();
        BeanUtils.copyProperties(advertisementUpdatePo, advertisement);
        advertisement.setBody(JSON.toJSONString(advertisementUpdatePo.getList()));
        Date time = new Date();
        advertisement.setUpdated(CurrentLoginUserAgent.getUser().getUserName());;
        advertisement.setUpdateTime(time);
        advertisementMapper.updateByPrimaryKey(advertisement);
        if (!preAdv.getBody().equals(advertisement.getBody())) {
            //不相同 更新广告
            CompletableFuture.runAsync(() -> {
                PlacedHospital hospital = new PlacedHospital();
                hospital.setAdvertisementId(preAdv.getId());
                List<PlacedHospital> placedHospitals = placedHospitalMapper.selectByCondition(hospital);
                for (PlacedHospital h : placedHospitals) {
                    JSONObject body = new JSONObject();
                    body.put("advertisement_id", hospital.getAdvertisementId());
                    Date now = new Date();
                    MqttMessageDTO message = new MqttMessageDTO();
                    message.setMsgSender("server_in");
                    message.setMsgReceiver(h.getTopic());
                    message.setMsgType(MqttMessageType.CHECK_ADVERTISEMENT_VERSION);
                    message.setMsgBody(body.toJSONString());
                    message.setSendTime(now);
//                message.setMsgIdentifier(msgIdent);
                    mqttMessageSender.send(message);
                }
            });

        }
        return new Result<>().ok();
    }

    @Override
    public Result<AdvertisementVO> queryById(Long id) {
        Advertisement advertisement = advertisementMapper.selectByPrimaryKey(id);
        if (advertisement != null) {
            AdvertisementVO advertisementVO = new AdvertisementVO();
            BeanUtils.copyProperties(advertisement, advertisementVO);
            advertisementVO.setList(JSON.parseArray(advertisement.getBody(), AdvertSmarPart.class));
            return new Result<AdvertisementVO>().ok(advertisementVO);
        } else {
            return null;
        }
    }

    @Override
    public Result<GenericPage<AdvertisementVO>> queryAll(AdvertisementQueryPO advertisementQueryPO) {
        int pageNo = advertisementQueryPO.getPageNo() == 0 ? 1 : advertisementQueryPO.getPageNo();
        int pageSize = advertisementQueryPO.getPageSize() == 0 ? 10 : advertisementQueryPO.getPageSize();
        List<AdvertisementVO> list = new ArrayList<>();
        Long businessId =CurrentLoginUserAgent.getBusinessId();
        Advertisement advertisement = new Advertisement();
        BeanUtils.copyProperties(advertisementQueryPO, advertisement);
        advertisement.setAgent(businessId);
        PageInfo<CustomerVO> pageInfo = PageHelper.startPage(pageNo, pageSize).doSelectPageInfo(() -> {
                    List<Advertisement> advertisements = advertisementMapper.selectAll(advertisement);
                    AdvertisementVO vo = null;
                    for (Advertisement a : advertisements) {
                        vo = new AdvertisementVO();
                        BeanUtils.copyProperties(a, vo);
                        vo.setList(JSON.parseArray(a.getBody(), AdvertSmarPart.class));
                        vo.setCreateTime(a.getCreateTime().getTime());
                        list.add(vo);
                    }
                });
        GenericPage<AdvertisementVO> genericPage = new GenericPage<>(pageSize, pageInfo.getTotal(), list);
        return new Result<GenericPage<AdvertisementVO>>().ok(genericPage);
    }

    @Override
    public Result<AdvertisementVO> queryAdvertisementBySn(String sn) {
        VenderDevice venderDevice = new VenderDevice();
        venderDevice.setDeviceSn(sn);
        List<VenderDevice> venderDevices = venderDeviceMapper.selectByCondition(venderDevice);
        if (venderDevices == null || venderDevices.size() == 0) {
            return new Result<>().error("设备不存在");
        }
        venderDevice = venderDevices.get(0);
        if (StringUtils.isEmpty(venderDevice.getHospitalId())) {
            return new Result<>().error("改设备未关联医院");
        }
        PlacedHospital placedHospital = placedHospitalMapper.selectByPrimaryKey(venderDevice.getHospitalId());
        if (StringUtils.isEmpty(placedHospital.getAdvertisementId())) {
            return new Result<>().error("改设备未关联广告");
        }
        Advertisement advertisement = advertisementMapper.selectByPrimaryKey(placedHospital.getAdvertisementId());
        if (advertisement == null) {
            return new Result<>().error("该设备关联的广告不存在或者已被删除");
        }
        AdvertisementVO advertisementVO = new AdvertisementVO();
        BeanUtils.copyProperties(advertisement, advertisementVO);
        if (!StringUtils.isEmpty(advertisement.getBody()))
            advertisementVO.setList(JSON.parseArray(advertisement.getBody(), AdvertSmarPart.class));
        return new Result<AdvertisementVO>().ok(advertisementVO);
    }

    @Override
    @Transactional
    public Result<Boolean> publishByAdvertisementId(Long advertisementId) {
        Advertisement advertisement = advertisementMapper.selectByPrimaryKey(advertisementId);
        if (advertisement==null){
            return new Result<>().error("广告不存在");
        }
        Advertisement aUpdate = new Advertisement();
        aUpdate.setId(advertisementId);
        aUpdate.setStatus(2);
        advertisementMapper.updateByPrimaryKey(aUpdate);
        PlacedHospital h = new PlacedHospital();
        h.setAdvertisementId(advertisementId);
        List<PlacedHospital> placedHospitals = placedHospitalMapper.selectByCondition(h);
        for (PlacedHospital hospital:placedHospitals){
            if (!StringUtils.isEmpty(hospital.getTopic())){
                //3.通知app端
                //发送通知
                JSONObject body = new JSONObject();
                body.put("advertisement_id",hospital.getAdvertisementId());
                Date now = new Date();
                MqttMessageDTO message=new MqttMessageDTO();
                message.setMsgSender("server_in");
                message.setMsgReceiver(hospital.getTopic());
                message.setMsgType(MqttMessageType.CHECK_ADVERTISEMENT_VERSION);
                message.setMsgBody(body.toJSONString());
                message.setSendTime(now);
//                message.setMsgIdentifier(msgIdent);
                mqttMessageSender.send(message);
            }
        }
        return new Result<>().ok();
    }


}
